/* * IronJacamar, a Java EE Connector Architecture implementation * Copyright 2016, Red Hat Inc, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the Eclipse Public License 1.0 as * published by the Free Software Foundation. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Eclipse * Public License for more details. * * You should have received a copy of the Eclipse Public License * along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.ironjacamar.codegenerator.code; import org.ironjacamar.codegenerator.BasicType; import org.ironjacamar.codegenerator.Definition; import org.ironjacamar.codegenerator.MethodForConnection; import java.io.IOException; import java.io.Writer; /** * A managed connection CodeGen. * * @author Jeff Zhang * @version $Revision: $ */ public class McCodeGen extends AbstractCodeGen { /** * Output class * * @param def definition * @param out Writer * @throws IOException ioException */ @Override public void writeClassBody(Definition def, Writer out) throws IOException { int indent = 1; out.write("public class " + getClassName(def) + " implements ManagedConnection"); writeLeftCurlyBracket(out, 0); writeEol(out); writeWithIndent(out, indent, "/** The logger */\n"); writeWithIndent(out, indent, "private static Logger log = Logger.getLogger(" + getSelfClassName(def) + ");\n\n"); writeWithIndent(out, indent, "/** The logwriter */\n"); writeWithIndent(out, indent, "private PrintWriter logwriter;\n\n"); writeWithIndent(out, indent, "/** ManagedConnectionFactory */\n"); writeWithIndent(out, indent, "private " + def.getMcfDefs().get(getNumOfMcf()).getMcfClass() + " mcf;\n\n"); writeWithIndent(out, indent, "/** Listeners */\n"); writeWithIndent(out, indent, "private List<ConnectionEventListener> listeners;\n\n"); writeWithIndent(out, indent, "/** Connections */\n"); if (def.getMcfDefs().get(getNumOfMcf()).isUseCciConnection()) writeWithIndent(out, indent, "private Set<" + def.getMcfDefs().get(getNumOfMcf()).getCciConnClass() + "> connections;\n\n"); else writeWithIndent(out, indent, "private Set<" + def.getMcfDefs().get(getNumOfMcf()).getConnImplClass() + "> connections;\n\n"); if (def.isSupportEis()) { writeWithIndent(out, indent, "/** Socket */\n"); writeWithIndent(out, indent, "private Socket socket;\n\n"); } //constructor writeWithIndent(out, indent, "/**\n"); writeWithIndent(out, indent, " * Default constructor\n"); writeWithIndent(out, indent, " * @param mcf mcf\n"); writeWithIndent(out, indent, " */\n"); writeWithIndent(out, indent, "public " + getClassName(def) + "(" + def.getMcfDefs().get(getNumOfMcf()).getMcfClass() + " mcf)"); if (def.isSupportEis()) { out.write(" throws ResourceException"); } writeLeftCurlyBracket(out, indent); writeWithIndent(out, indent + 1, "this.mcf = mcf;\n"); writeWithIndent(out, indent + 1, "this.logwriter = null;\n"); writeWithIndent(out, indent + 1, "this.listeners = Collections.synchronizedList(new ArrayList<ConnectionEventListener>(1));\n"); if (def.getMcfDefs().get(getNumOfMcf()).isUseCciConnection()) writeWithIndent(out, indent + 1, "this.connections = new HashSet<" + def.getMcfDefs().get(getNumOfMcf()).getCciConnClass() + ">();"); else writeWithIndent(out, indent + 1, "this.connections = new HashSet<" + def.getMcfDefs().get(getNumOfMcf()).getConnImplClass() + ">();"); if (def.isSupportEis()) { writeEol(out); writeWithIndent(out, indent + 1, "this.socket = null; // TODO: Initialize me"); } writeRightCurlyBracket(out, indent); writeEol(out); writeConnection(def, out, indent); writeLifecycle(def, out, indent); writeConnectionEventListener(def, out, indent); writeLogWriter(def, out, indent); writeTransaction(def, out, indent); writeMetaData(def, out, indent); writeMethod(def, out, indent); writeRightCurlyBracket(out, 0); } /** * Output class import * * @param def definition * @param out Writer * @throws IOException ioException */ @Override public void writeImport(Definition def, Writer out) throws IOException { out.write("package " + def.getRaPackage() + ";\n\n"); if (def.isSupportEis()) { out.write("import java.io.IOException;\n"); } out.write("import java.io.PrintWriter;\n"); if (def.isSupportEis()) { out.write("import java.net.Socket;\n"); } out.write("import java.util.ArrayList;\n"); out.write("import java.util.Collections;\n"); out.write("import java.util.HashSet;\n"); out.write("import java.util.List;\n"); out.write("import java.util.Set;\n"); importLogging(def, out); out.write("import javax.resource.NotSupportedException;\n"); out.write("import javax.resource.ResourceException;\n"); out.write("import javax.resource.spi.ConnectionEvent;\n"); out.write("import javax.resource.spi.ConnectionEventListener;\n"); out.write("import javax.resource.spi.ConnectionRequestInfo;\n"); out.write("import javax.resource.spi.LocalTransaction;\n"); out.write("import javax.resource.spi.ManagedConnection;\n"); out.write("import javax.resource.spi.ManagedConnectionMetaData;\n\n"); out.write("import javax.security.auth.Subject;\n"); out.write("import javax.transaction.xa.XAResource;\n\n"); } /** * get this class name * * @param def definition * @return String class name */ @Override public String getClassName(Definition def) { return def.getMcfDefs().get(getNumOfMcf()).getMcClass(); } /** * Output Connection method * * @param def definition * @param out Writer * @param indent space number * @throws IOException ioException */ private void writeConnection(Definition def, Writer out, int indent) throws IOException { writeWithIndent(out, indent, "/**\n"); writeWithIndent(out, indent, " * Creates a new connection handle for the underlying physical connection \n"); writeWithIndent(out, indent, " * represented by the ManagedConnection instance. \n"); writeWithIndent(out, indent, " *\n"); writeWithIndent(out, indent, " * @param subject Security context as JAAS subject\n"); writeWithIndent(out, indent, " * @param cxRequestInfo ConnectionRequestInfo instance\n"); writeWithIndent(out, indent, " * @return generic Object instance representing the connection handle. \n"); writeWithIndent(out, indent, " * @throws ResourceException generic exception if operation fails\n"); writeWithIndent(out, indent, " */\n"); writeWithIndent(out, indent, "public Object getConnection(Subject subject,\n"); writeWithIndent(out, indent + 1, "ConnectionRequestInfo cxRequestInfo) throws ResourceException"); writeLeftCurlyBracket(out, indent); writeLogging(def, out, indent + 1, "trace", "getConnection"); writeIndent(out, indent + 1); if (def.getMcfDefs().get(getNumOfMcf()).isUseCciConnection()) out.write(def.getMcfDefs().get(getNumOfMcf()).getCciConnClass() + " connection = new " + def.getMcfDefs().get(getNumOfMcf()).getCciConnClass() + "();\n"); else out.write(def.getMcfDefs().get(getNumOfMcf()).getConnImplClass() + " connection = new " + def.getMcfDefs().get(getNumOfMcf()).getConnImplClass() + "(this, mcf);\n"); writeWithIndent(out, indent + 1, "connections.add(connection);\n"); writeWithIndent(out, indent + 1, "return connection;"); writeRightCurlyBracket(out, indent); writeEol(out); writeWithIndent(out, indent, "/**\n"); writeWithIndent(out, indent, " * Used by the container to change the association of an \n"); writeWithIndent(out, indent, " * application-level connection handle with a ManagedConneciton instance.\n"); writeWithIndent(out, indent, " *\n"); writeWithIndent(out, indent, " * @param connection Application-level connection handle\n"); writeWithIndent(out, indent, " * @throws ResourceException generic exception if operation fails\n"); writeWithIndent(out, indent, " */\n"); writeWithIndent(out, indent, "public void associateConnection(Object connection) throws ResourceException"); writeLeftCurlyBracket(out, indent); writeLogging(def, out, indent + 1, "trace", "associateConnection", "connection\n"); writeWithIndent(out, indent + 1, "if (connection == null)\n"); writeWithIndent(out, indent + 2, "throw new ResourceException(\"Null connection handle\");\n\n"); writeWithIndent(out, indent + 1, "if (!(connection instanceof "); if (def.getMcfDefs().get(getNumOfMcf()).isUseCciConnection()) out.write(def.getMcfDefs().get(getNumOfMcf()).getCciConnClass()); else out.write(def.getMcfDefs().get(getNumOfMcf()).getConnImplClass()); out.write("))\n"); writeWithIndent(out, indent + 2, "throw new ResourceException(\"Wrong connection handle\");\n\n"); if (def.getMcfDefs().get(getNumOfMcf()).isUseCciConnection()) writeWithIndent(out, indent + 1, def.getMcfDefs().get(getNumOfMcf()).getCciConnClass()); else writeWithIndent(out, indent + 1, def.getMcfDefs().get(getNumOfMcf()).getConnImplClass()); out.write(" handle = ("); if (def.getMcfDefs().get(getNumOfMcf()).isUseCciConnection()) out.write(def.getMcfDefs().get(getNumOfMcf()).getCciConnClass()); else out.write(def.getMcfDefs().get(getNumOfMcf()).getConnImplClass()); out.write(")connection;\n"); writeWithIndent(out, indent + 1, "handle.setManagedConnection(this);\n"); writeWithIndent(out, indent + 1, "connections.add(handle);"); writeRightCurlyBracket(out, indent); writeEol(out); } /** * Output Lifecycle method * * @param def definition * @param out Writer * @param indent space number * @throws IOException ioException */ private void writeLifecycle(Definition def, Writer out, int indent) throws IOException { writeWithIndent(out, indent, "/**\n"); writeWithIndent(out, indent, " * Application server calls this method to force any cleanup on the ManagedConnection instance.\n"); writeWithIndent(out, indent, " *\n"); writeWithIndent(out, indent, " * @throws ResourceException generic exception if operation fails\n"); writeWithIndent(out, indent, " */\n"); writeWithIndent(out, indent, "public void cleanup() throws ResourceException"); writeLeftCurlyBracket(out, indent); writeLogging(def, out, indent + 1, "trace", "cleanup"); writeWithIndent(out, indent + 1, "for ("); if (def.getMcfDefs().get(getNumOfMcf()).isUseCciConnection()) out.write(def.getMcfDefs().get(getNumOfMcf()).getCciConnClass()); else out.write(def.getMcfDefs().get(getNumOfMcf()).getConnImplClass()); out.write(" connection : connections)"); writeLeftCurlyBracket(out, indent + 1); writeWithIndent(out, indent + 2, "connection.setManagedConnection(null);"); writeRightCurlyBracket(out, indent + 1); writeWithIndent(out, indent + 1, "connections.clear();\n"); writeRightCurlyBracket(out, indent); writeEol(out); writeWithIndent(out, indent, "/**\n"); writeWithIndent(out, indent, " * Destroys the physical connection to the underlying resource manager.\n"); writeWithIndent(out, indent, " *\n"); writeWithIndent(out, indent, " * @throws ResourceException generic exception if operation fails\n"); writeWithIndent(out, indent, " */\n"); writeWithIndent(out, indent, "public void destroy() throws ResourceException"); writeLeftCurlyBracket(out, indent); writeLogging(def, out, indent + 1, "trace", "destroy"); if (def.isSupportEis()) { writeEol(out); writeWithIndent(out, indent + 1, "if (socket != null)"); writeLeftCurlyBracket(out, indent + 1); writeWithIndent(out, indent + 2, "try"); writeLeftCurlyBracket(out, indent + 2); writeWithIndent(out, indent + 3, "socket.close();"); writeRightCurlyBracket(out, indent + 2); writeWithIndent(out, indent + 2, "catch (IOException ioe)"); writeLeftCurlyBracket(out, indent + 2); writeWithIndent(out, indent + 3, "// Ignore"); writeRightCurlyBracket(out, indent + 2); writeRightCurlyBracket(out, indent + 1); } writeRightCurlyBracket(out, indent); writeEol(out); } /** * Output ConnectionEventListener method * * @param def definition * @param out Writer * @param indent space number * @throws IOException ioException */ private void writeConnectionEventListener(Definition def, Writer out, int indent) throws IOException { writeWithIndent(out, indent, "/**\n"); writeWithIndent(out, indent, " * Adds a connection event listener to the ManagedConnection instance.\n"); writeWithIndent(out, indent, " *\n"); writeWithIndent(out, indent, " * @param listener A new ConnectionEventListener to be registered\n"); writeWithIndent(out, indent, " */\n"); writeWithIndent(out, indent, "public void addConnectionEventListener(ConnectionEventListener listener)"); writeLeftCurlyBracket(out, indent); writeLogging(def, out, indent + 1, "trace", "addConnectionEventListener", "listener"); writeWithIndent(out, indent + 1, "if (listener == null)\n"); writeWithIndent(out, indent + 2, "throw new IllegalArgumentException(\"Listener is null\");\n"); writeWithIndent(out, indent + 1, "listeners.add(listener);"); writeRightCurlyBracket(out, indent); writeEol(out); writeWithIndent(out, indent, "/**\n"); writeWithIndent(out, indent, " * Removes an already registered connection event listener from the ManagedConnection instance.\n"); writeWithIndent(out, indent, " *\n"); writeWithIndent(out, indent, " * @param listener already registered connection event listener to be removed\n"); writeWithIndent(out, indent, " */\n"); writeWithIndent(out, indent, "public void removeConnectionEventListener(ConnectionEventListener listener)"); writeLeftCurlyBracket(out, indent); writeLogging(def, out, indent + 1, "trace", "removeConnectionEventListener", "listener"); writeWithIndent(out, indent + 1, "if (listener == null)\n"); writeWithIndent(out, indent + 2, "throw new IllegalArgumentException(\"Listener is null\");\n"); writeWithIndent(out, indent + 1, "listeners.remove(listener);"); writeRightCurlyBracket(out, indent); writeEol(out); writeWithIndent(out, indent, "/**\n"); writeWithIndent(out, indent, " * Close handle\n"); writeWithIndent(out, indent, " *\n"); writeWithIndent(out, indent, " * @param handle The handle\n"); writeWithIndent(out, indent, " */\n"); writeWithIndent(out, indent, "void closeHandle("); if (def.getMcfDefs().get(getNumOfMcf()).isUseCciConnection()) out.write(def.getMcfDefs().get(getNumOfMcf()).getCciConnClass() + " handle)"); else out.write(def.getMcfDefs().get(getNumOfMcf()).getConnInterfaceClass() + " handle)"); writeLeftCurlyBracket(out, indent); writeWithIndent(out, indent + 1, "connections.remove(("); if (def.getMcfDefs().get(getNumOfMcf()).isUseCciConnection()) out.write(def.getMcfDefs().get(getNumOfMcf()).getCciConnClass()); else out.write(def.getMcfDefs().get(getNumOfMcf()).getConnImplClass()); out.write(")handle);\n"); writeWithIndent(out, indent + 1, "ConnectionEvent event = new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED);\n"); writeWithIndent(out, indent + 1, "event.setConnectionHandle(handle);\n"); writeWithIndent(out, indent + 1, "for (ConnectionEventListener cel : listeners)"); writeLeftCurlyBracket(out, indent + 1); writeWithIndent(out, indent + 2, "cel.connectionClosed(event);"); writeRightCurlyBracket(out, indent + 1); writeRightCurlyBracket(out, indent); writeEol(out); } /** * Output Transaction method * * @param def definition * @param out Writer * @param indent space number * @throws IOException ioException */ private void writeTransaction(Definition def, Writer out, int indent) throws IOException { writeWithIndent(out, indent, "/**\n"); writeWithIndent(out, indent, " * Returns an <code>javax.resource.spi.LocalTransaction</code> instance.\n"); writeWithIndent(out, indent, " *\n"); writeWithIndent(out, indent, " * @return LocalTransaction instance\n"); writeWithIndent(out, indent, " * @throws ResourceException generic exception if operation fails\n"); writeWithIndent(out, indent, " */\n"); writeWithIndent(out, indent, "public LocalTransaction getLocalTransaction() throws ResourceException"); writeLeftCurlyBracket(out, indent); if (def.getSupportTransaction().equals("NoTransaction")) { writeWithIndent(out, indent + 1, "throw new NotSupportedException(\"getLocalTransaction() not supported\");"); } else { writeLogging(def, out, indent + 1, "trace", "getLocalTransaction"); writeWithIndent(out, indent + 1, "return null;"); } writeRightCurlyBracket(out, indent); writeEol(out); writeWithIndent(out, indent, "/**\n"); writeWithIndent(out, indent, " * Returns an <code>javax.transaction.xa.XAresource</code> instance. \n"); writeWithIndent(out, indent, " *\n"); writeWithIndent(out, indent, " * @return XAResource instance\n"); writeWithIndent(out, indent, " * @throws ResourceException generic exception if operation fails\n"); writeWithIndent(out, indent, " */\n"); writeWithIndent(out, indent, "public XAResource getXAResource() throws ResourceException"); writeLeftCurlyBracket(out, indent); if (def.getSupportTransaction().equals("NoTransaction")) { writeWithIndent(out, indent + 1, "throw new NotSupportedException(\"getXAResource() not supported\");"); } else { writeLogging(def, out, indent + 1, "trace", "getXAResource"); writeWithIndent(out, indent + 1, "return null;"); } writeRightCurlyBracket(out, indent); writeEol(out); } /** * Output MetaData method * * @param def definition * @param out Writer * @param indent space number * @throws IOException ioException */ private void writeMetaData(Definition def, Writer out, int indent) throws IOException { writeWithIndent(out, indent, "/**\n"); writeWithIndent(out, indent, " * Gets the metadata information for this connection's underlying EIS resource manager instance. \n"); writeWithIndent(out, indent, " *\n"); writeWithIndent(out, indent, " * @return ManagedConnectionMetaData instance\n"); writeWithIndent(out, indent, " * @throws ResourceException generic exception if operation fails\n"); writeWithIndent(out, indent, " */\n"); writeWithIndent(out, indent, "public ManagedConnectionMetaData getMetaData() throws ResourceException"); writeLeftCurlyBracket(out, indent); writeLogging(def, out, indent + 1, "trace", "getMetaData"); writeWithIndent(out, indent + 1, "return new " + def.getMcfDefs().get(getNumOfMcf()).getMcMetaClass() + "();"); writeRightCurlyBracket(out, indent); writeEol(out); } /** * Output methods * * @param def definition * @param out Writer * @param indent space number * @throws IOException ioException */ private void writeMethod(Definition def, Writer out, int indent) throws IOException { if (def.getMcfDefs().get(getNumOfMcf()).isDefineMethodInConnection()) { if (def.getMcfDefs().get(getNumOfMcf()).getMethods().size() > 0) { for (MethodForConnection method : def.getMcfDefs().get(getNumOfMcf()).getMethods()) { writeMethodSignature(out, indent, method); writeLeftCurlyBracket(out, indent); writeLogging(def, out, indent + 1, "trace", method.getMethodName()); if (!method.getReturnType().equals("void")) { writeEol(out); if (BasicType.isPrimitiveType(method.getReturnType())) { writeWithIndent(out, indent + 1, "return " + BasicType.defaultValue(method.getReturnType()) + ";"); } else { writeWithIndent(out, indent + 1, "return null;"); } } writeRightCurlyBracket(out, indent); } } } else { writeSimpleMethodSignature(out, indent, " * Call me", "void callMe()"); writeLeftCurlyBracket(out, indent); writeLogging(def, out, indent + 1, "trace", "callMe"); writeRightCurlyBracket(out, indent); } } }